<?php

function remote_request($url,$deserialize_type=0, $postFields="", $conn_timeout=2,$timeout=2, $method="post")
{
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER,1 ); //return, don't print
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,$conn_timeout);
	curl_setopt($ch, CURLOPT_MUTE,1); // complain silently
	curl_setopt($ch, CURLOPT_TIMEOUT,$timeout);
	if($method== "post")
	{
		curl_setopt($ch, CURLOPT_POST, 1);
		$post_str = "";
		if(!empty($postFields) && is_array($postFields))
		{
			foreach($postFields as $key=>$val)
			{
				$post_str .= "&$key=".urlencode($val);
			}
			$post_str = trim($post_str,"&");
		}
		else
		{
			$post_str = $postFields;
		}
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post_str);
	}
	$response = curl_exec($ch);
	if (curl_errno($ch) == 0)
	{
		if($deserialize_type == TYPE_XML)
		{
			$response = xmlToArray($response);
			return $response;
		}
		elseif($deserialize_type == TYPE_JSON)
		{
			//$response = preg_replace("/<!--(.*)-->$/", "",$response);
			return json_decode($response, true);
		}
		else
		{
			return $response;
		}
	}
	else
	{
		return false;
	}
}

function httpget($url, $conn_timeout = 0.5, $rw_timeout = 10000)
{
	$rw_timeout2["r"] = $rw_timeout2["w"] = round($rw_timeout / (100 * 10000), 4);
	return httpRequestCore($url, "GET", null, $conn_timeout, $rw_timeout2);
}

function httppost($url, $postdata, $conn_timeout = 0.5, $rw_timeout = 10000)
{
	$rw_timeout2["r"] = $rw_timeout2["w"] = round($rw_timeout / (100 * 10000), 4);
	return httpRequestCore($url, "POST", $postdata, $conn_timeout, $rw_timeout2);
}

/**
 * httpRequestCore v2.0 (for linux/unix only)
 *
 * use socket.so library, created by <lowellzhong@gmail.com>
 */
function httpRequestCore($url, $method = "GET", $post_data = null, $conn_timeout = 20.0, $rw_timeout = array("r" => 20.0, "w" => 1.0))
{
	/* parse url */
	$urlInfo = parse_url($url);
	$urlInfo["path"] = empty($urlInfo["path"]) ? "/" : $urlInfo["path"];
	$urlInfo["port"] = empty($urlInfo["port"]) ? "80" : $urlInfo["port"];
	$urlInfo["ip"] = gethostbyname($urlInfo["host"]);
	$urlInfo["request"] =  $urlInfo["path"]	.
	(empty($urlInfo["query"]) ? "" : "?" . $urlInfo["query"]) .
	(empty($urlInfo["fragment"]) ? "" : "#" . $urlInfo["fragment"]);


	/* create socket handle */
	$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
	if(!$sock){
		trigger_error(socket_strerror(socket_last_error()));
		return false;
	}

	/* connect host with timeout */
	socket_set_nonblock($sock);
	@socket_connect($sock, $urlInfo["ip"], $urlInfo["port"]);
	socket_set_block($sock);
	$ret = socket_select($fd_read = array($sock), $fd_write = array($sock), $except = NULL, floor($conn_timeout), fmod($conn_timeout, 1) * 1000000);
	if($ret === false)
	{
		trigger_error(socket_strerror(socket_last_error()));
		return false;
	}else if ($ret != 1)
	{
		trigger_error("connect ${urlInfo['host']}(${urlInfo['ip']}:${urlInfo['port']}) timeout");
		return false;
	}

	/* begin send data */
	$method = strtoupper($method);
	$in = $method . " " . $urlInfo["request"] . " HTTP/1.0\r\n";
	$in .= "Accept: */*\r\n";
	$in .= "User-Agent: Lowell-Agent\r\n";
	$in .= "Host: " . $urlInfo["host"] . "\r\n";
	if($method == "POST")
	{
		$in .= "Content-type: application/x-www-form-urlencoded\r\n";
		$post_tmp = "";
		if(is_array($post_data))
		{
			foreach($post_data as $key => $val)
			{
				$post_tmp .= (empty($post_tmp) ? "" : "&") . urlencode($key) . "=" . urlencode($val);
			}
		}
		$in .= "Content-Length: " . strlen($post_tmp) . "\r\n";
	}
	$in .= "Connection: Close\r\n\r\n";
	if(!empty($post_tmp))
	{
		$in .= $post_tmp . "\r\n\r\n";
	}

	//socket_set_option($sock, SOL_SOCKET, SO_SNDTIMEO, array("sec" => floor($rw_timeout["w"]), "usec" => fmod($rw_timeout["w"], 1) * 1000000));

	if (false === socket_write($sock, $in, strlen($in))) {
		trigger_error(socket_strerror(socket_last_error()));
		socket_close($sock);
		return false;
	}
	unset($in);

	/* begin receive data */
	//socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec" => floor($rw_timeout["r"]), "usec" => fmod($rw_timeout["r"], 1) * 1000000));
	$out = "";
	while ($buff = socket_read($sock, 8192)) {
		$out .= $buff;
	}
	socket_close($sock);

	$pos = strpos($out, "\r\n\r\n");
	$head = substr($out, 0, $pos);
	$status = substr($head, 0, strpos($head, "\r\n"));
	$body = substr($out, $pos + 4, strlen($out) - ($pos + 4));
	if (1 != preg_match("/^HTTP\/\d\.\d\s([\d]+)\s.*$/", $status, $matches))
	{
		trigger_error("http status error:" . (isset($matches[1]) ? $matches[1] : "NULL"));
		return false;
	}

	if (2 != intval($matches[1]) / 100)
	{
		trigger_error("http syntax error: " . $matches[1]);
		return false;
	}

	return $body;	/* success */
}
?>